<?php
/**
 * Api 检查抛出错误
 *
 * @author Zeon <scplay@gmail.com>
 * @date 2018/7/27
 * @copyright PanxSoft Inc.
 */
namespace App\Services\Utils;

use App\Exceptions\ApiAbstractException;
use App\Exceptions\ApiException;
use App\Exceptions\ApiErrCode;
use Illuminate\Http\Request;

/**
 * Trait ApiChecker
 *
 * @package App\Services\Utils
 */
trait ApiChecker
{
    /**
     * @param $token
     *
     * @throws ApiAbstractException|\Exception
     */
    protected function passwordVerifyCheck($token)
    {
        if (! $token) {
            throw New ApiException(ApiErrCode::INVALID_PASSWORD, trans('checker.password_verify_error'));
        }
    }


    /**
     * @param Request $request
     * @param string $tip
     *
     * @throws ApiAbstractException|\Exception
     */
    protected function checkJwtTokenExist(Request $request, $tip='')
    {
        if (! $request->get('token') && ! $request->bearerToken()) {
            throw new ApiException(ApiErrCode::JWT_TOKEN_NOT_FOUND, $tip ?: trans('checker.check_jwt_token_exist'));
        }
    }

    /**
     * 请求参数错误
     *
     * @param $success
     * @param string $tip
     * @throws ApiAbstractException|\Exception
     */
    protected function checkParamError($success, $tip): void
    {
        if (! $success) {
            throw new ApiException(ApiErrCode::REQUEST_PARAMS_ERROR, $tip);
        }
    }

    /**
     * @param $param
     * @param string $tip
     *
     * @throws ApiAbstractException|\Exception
     */
    protected function checkParamExist($param, $tip = ''): void
    {
        if (! $param) {
            throw new ApiException(ApiErrCode::REQUEST_PARAMS_EMPTY,
                trans('checker.check_param_exist', ['tip'=>$tip]));
        }
    }

    /**
     * @param $param
     * @param $range
     * @param string $tip
     * @throws ApiAbstractException|\Exception
     */
    protected function checkParamInRange($param, $range, $tip='' ): void
    {
        if (! in_array($param, $range)) {
            throw new ApiException(ApiErrCode::REQUEST_PARAMS_NOT_IN_RANGE,
                trans('checker.check_param_in_range', ['tip'=>$tip ?: trans('checker.default_param')]));
        }
    }
    
    /**
     * 检查访问权限
     *
     * @param mixed $can_access
     * @throws ApiAbstractException|\Exception
     */
    protected function checkCanAccess($can_access): void
    {
        if (! $can_access) {
            throw new ApiException(ApiErrCode::ADMIN_AUTH_NOT_FOUND,
                trans('checker.check_can_access'));
        }
    }

    /**
     * 检查操作权限
     *
     * @param $editable
     * @param string $tip
     * @param int $code
     *
     * @throws ApiAbstractException|\Exception
     */
    protected function checkCanOperate($editable, $tip = '', $code = ApiErrCode::OPERATOR_NOT_ALLOWED): void
    {
        if (! $editable) {
            throw new ApiException($code,
                trans('checker.check_can_operate', ['tip'=>$tip ?: trans('checker.check_operate_param')]));
        }
    }

    /**
     * 检查条件必须为否
     *
     * @param $error_state
     * @param string $tip
     * @param int $code
     *
     * @throws ApiAbstractException|\Exception
     */
    protected function checkUnless($error_state, $tip='', $code = ApiErrCode::OPERATOR_NOT_ALLOWED): void
    {
        if ($error_state) {
            throw new ApiException($code, $tip ?: trans('checker.check_unless'));
        }
    }

    /**
     * 检查数据必须存在
     *
     * @param $item
     * @param string $tip
     * @param null $code
     *
     * @throws ApiAbstractException|\Exception
     */
    protected function checkItemExist($item, $tip = null, $code = null): void
    {
        if (! $item) {
            $tip = $tip ?: trans('checker.check_item_tip');

            throw new ApiException(
                $code ?: ApiErrCode::DB_ITEM_NOT_FOUND,
                trans('checker.check_item_exist', compact('tip'))
            );
        }
    }

    /**
     * 检查条件应为真，错误码自定义
     *
     * @param $is_true
     * @param string $tip
     * @param null $code
     *
     * @throws ApiAbstractException|\Exception
     */
    protected function checkIsTrue($is_true, $tip = null, $code = null): void
    {
        if (! $is_true) {
            throw new ApiException(
                $code ?: ApiErrCode::CUSTOMIZE_ERROR,
                $tip ?: trans('checker.check_item_tip')
            );
        }
    }

    /**
     * 检查数据可以修改
     *
     * @param $editable
     * @param string $tip
     *
     * @throws ApiAbstractException|\Exception
     */
    protected function checkItemEditable($editable, $tip=''): void
    {
        if (! $editable) {
            throw new ApiException(
                ApiErrCode::DB_NOT_EDITABLE,
                trans('checker.check_item_editable', ['tip'=>$tip ?: trans('checker.check_item_tip')])
            );
        }
    }

    /**
     * 检查操作成功
     *
     * @param $success
     * @param string $tip
     *
     * @throws ApiAbstractException|\Exception
     */
    protected function checkOperateSuccess($success, $tip=''): void
    {
        if (! $success) {
            throw new ApiException(ApiErrCode::OPERATE_FAILED,
                trans('checker.check_operate_success', ['tip'=>$tip ?: trans('checker.check_operate_tip')]));
        }
    }

    /**
     * 未定义错误
     *
     * @param mixed $success
     * @param int $code
     * @param string $tip
     *
     * @throws ApiAbstractException|\Exception
     */
    protected function checkUndefinedError($success, $tip='', $code = ApiErrCode::UNKNOWN_ERROR): void
    {
        if (! $success) {
            throw new ApiException($code, $tip ?: trans('checker.check_undefined_error'));
        }
    }

    /**
     * 直接失败抛错
     *
     * @param string $tip
     * @param int $code
     *
     * @throws ApiAbstractException|\Exception
     */
    protected function checkFailed(string $tip, int $code = ApiErrCode::UNKNOWN_ERROR): void
    {
        throw new ApiException($code, $tip);
    }

    /**
     * 检查需要强制操作参数
     *
     * @param $force
     * @param string $tip
     * @param int $code
     *
     * @throws ApiAbstractException|\Exception
     */
    protected function checkForceOperate($force, $tip='', $code = ApiErrCode::NEED_FORCE_OPERATE): void
    {
        if (! $force) {
            throw new ApiException($code, $tip ?: trans('checker.check_force_operate'));
        }
    }

    /**
     * 需要强制操作
     *
     * @param string $tip
     * @param int $code
     * @throws ApiAbstractException|\Exception
     */
    protected function requestForceOperate($tip = '', $code = ApiErrCode::NEED_FORCE_OPERATE): void
    {
        $this->checkForceOperate(\request()->get('force'), $tip ?: trans('checker.check_force_operate'), $code);
    }

    /**
     * 检测集合是否是空的
     *
     * @param \Countable $success
     * @param string $tip
     * @param int $code
     *
     * @throws ApiAbstractException|\Exception
     */
    protected function checkCollectionFilled(
        \Countable $success,
        $tip='',
        $code = ApiErrCode::COLLECTION_EMPTY_ERROR
    ): void
    {
        if ($success->count() <= 0) {
            throw new ApiException($code, $tip ?: trans('checker.check_collection_exist'));
        }
    }
}